/*
** Method 1: CURAND_RNG_PSEUDO_XORWOW from curand
** Method 2: CURAND_RNG_PSEUDO_XORWOW (CURAND_ORDERING_PSEUDO_SEEDED) from curand
** Method 3: CURAND_RNG_PSEUDO_MRG32K3A from curand
** Method 4: CURAND_RNG_PSEUDO_MTGP32 from curand
** Method 5: CURAND_RNG_PSEUDO_PHILOX4_32_10 from curand

** Method 6: VSL_BRNG_MCG31 from MKL
** Method 7: VSL_BRNG_R250 from MKL
** Method 8: VSL_BRNG_MRG32K3A from MKL
** Method 9: VSL_BRNG_MCG59 from MKL
** Method 10: VSL_BRNG_WH from MKL
** Method 11: VSL_BRNG_MT19937 from MKL
** Method 12: VSL_BRNG_MT2203 from MKL
** Method 13: VSL_BRNG_SFMT19937 from MKL

** Method 14: LCG from C rand()
** Method 15: KISS
*/

#ifndef __LIBRNG_H__
#define __LIBRNG_H__

#include "curand.h"
#include "mkl_vsl.h"

#ifdef __cplusplus
extern "C" {
#endif


typedef enum 
{ 
	ILLEGAL = -1, CURAND1=1, CURAND2, CURAND3, CURAND4, CURAND5, MKL1, MKL2, MKL3, MKL4, MKL5, MKL6, MKL7, MKL8, LCG, KISS 
} RNG_ID;

typedef struct
{
	RNG_ID method;
	VSLStreamStatePtr stream; // MKL
	VSLStreamStatePtr stream_d; // for double precision user defined RNG
	curandGenerator_t gen; // CURAND	
} RNGStatus;

void createRNG( RNG_ID method, RNGStatus *status, unsigned int seed );
void destroyRNG( RNGStatus *status );

void generateUniform( RNGStatus *status, float*  buffer, int count, float lower, float upper );
void generateUniformDouble( RNGStatus *status, double*  buffer, int count, double lower, double upper );
void generateNormal( RNGStatus *status, float*  buffer, int count, float mean, float stdev );
void generateNormalDouble( RNGStatus *status, double*  buffer, int count, double mean, double stdev );

void generateUniform_d( RNGStatus *status, float*  buffer, int count, float lower, float upper );
void generateUniformDouble_d( RNGStatus *status, double*  buffer, int count, double lower, double upper );
void generateNormal_d( RNGStatus *status, float*  buffer, int count, float mean, float stdev );
void generateNormalDouble_d( RNGStatus *status, double*  buffer, int count, double mean, double stdev );


#ifdef __cplusplus
}
#endif

#endif // __LIBRNG_H__